package top.rainbowecho.notify.domain.model.email.decorator;

import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.multipart.MultipartFile;
import top.rainbowecho.common.mq.mo.MailMeta;
import top.rainbowecho.common.util.ExceptionMessageContent;
import top.rainbowecho.notify.domain.model.email.EmailDecorator;
import top.rainbowecho.notify.domain.model.email.Mail;
import top.rainbowecho.notify.domain.model.email.db.entity.MailTemplate;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;

import static cn.hutool.core.collection.CollUtil.isNotEmpty;

/**
 * 附件邮件发送装饰器为邮件发送添加发送多个附件的功能，但必须作为最后一个装饰器使用
 *
 * @author rainbow
 * @since 2019/11/28 14:22
 */
public class AttachMail extends EmailDecorator {
    public AttachMail(Mail mail) {
        // 不仅要初始化父类的mail，也要初始化自己的相关属性，因为会嵌套使用
        super(mail);
        this.setFrom(mail.getFrom());
        this.setSender(mail.getSender());
        this.setTemplateEngine(mail.getTemplateEngine());
        this.setTemplateMapper(mail.getTemplateMapper());
    }

    @Override
    public MimeMessage generateHtmlMail(MailMeta info) throws MessagingException, IOException {
        // 一定是使用this.getMail()进行上级调用
        MimeMessage message = this.getMail().generateHtmlMail(info);

        // 发送附件邮件时，内容和模板两者不能同时为空
        if (StringUtils.isEmpty(info.getContent()) && StringUtils.isEmpty(info.getTemplate())) {
            throw new NullPointerException(ExceptionMessageContent.EMPTY_CONTENT_TO_ATTACH);
        }

        // 将上传的文件添加为附件
        if (isNotEmpty(info.getFiles())) {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            MailTemplate templateRecord = this.getTemplateMapper().findMailTemplateBySign(info.getTemplate());
            // 发送附件邮件内容必须不能为空，但在经过装饰器调用后，内容会变为空，因此需要重新设置一下
            String text = StringUtils.isEmpty(info.getContent()) ?
                    TemplateMail.convert(this.getMail().getTemplateEngine(), info, templateRecord.getContext())
                    : info.getContent();
            helper.setText(text, true);
            for (MultipartFile file : info.getFiles()) {
                // 以本地文件名上传，可以保留文件名的拓展名信息，从而使图片等文件可以预览
                helper.addAttachment(file.getName(), file);
            }
        }
        return message;
    }
}
